<?php
/**
 * Created by PhpStorm.
 * User: jaylen
 * Date: 2020-10-23
 * Time: 18:01
 */

namespace app\admin\model\traits;


use app\admin\service\WXWebAppData;
use app\common\exception\LoginException;
use app\common\exception\ParameterException;
use app\common\exception\UserException;
use app\common\model\WeChatUser;
use app\common\service\JWTToken;
use app\common\validate\IDMustBeRequire;
use think\db\Raw;
use think\facade\Cache;
use think\facade\Request;
use app\admin\validate\Admin as Validate;

trait AdminWeChatUser
{

    /**
     * 微信管理员登陆
     * @param array $data
     * @return string
     */
    public static function weChatAdminLogin(array $data)
    {
        $validate = new Validate();
        if (!$validate->scene('wx_login')->check($data)) {
            throw new ParameterException([
                'msg' => $validate->getError()
            ]);
        }

        $webApp = new WXWebAppData();
        $access_token = $webApp->getWebAppAccessToken($data['code']);
        if (empty($access_token) ||
            !isset($access_token['access_token']) ||
            !isset($access_token['unionid']) ||
            empty($access_token['access_token']) ||
            empty($access_token['unionid'])) {
            throw new \Exception('[微信网站应用]获取access_token失败，access_token为空');
        }

        $we_chat_admin = WeChatUser::with(['admin' => function($query) {
            $query->where([['status','=',1]])->field(['id','user_name','status']);
        }])->where([['unionid','=',$access_token['unionid']],['web_openid','=',$access_token['openid']]])
            ->find();

        $admin = (!$we_chat_admin || !$we_chat_admin->admin || $we_chat_admin->admin->isEmpty()) ? [] : $we_chat_admin->admin->toArray()[0];

        if (empty($we_chat_admin) || empty($admin)) {
            write_system_log('微信管理员登陆失败，用户不存在,web_openid:' . $access_token['openid']);
            throw new UserException();
        }

        write_system_log('微信管理员登陆成功', $we_chat_admin->nick_name);

        // 生成jwt token
        $jwt_token =  (string)(new JWTToken())->generateJWTToken([
            'uid' => $admin['id'],
            'user_name' => $admin['user_name']
        ]);

        // 得到随机字符串
        $code = \md5($data['code']);
        $key = self::getTokenRedisKey($code);

        // 将token存放在Cache中(有效期为30s)
        Cache::store('redis')->set($key,$jwt_token, self::CODE_TOKEN_EXPIRE);

        return $code;
    }

    /**
     * 通过code获取jwt_token
     * @param $code
     * @return mixed
     */
    public static function getJWTTokenByCode($code)
    {
        $key = self::getTokenRedisKey($code);

        $token = Cache::store('redis')->get($key, '');

        if (empty($token)) {
            throw new LoginException([
                'code' => 404,
                'msg' => 'token不存在',
                'errorCode' => 60101
            ]);
        }

        return $token;
    }

    /**
     * 添加微信管理员
     * @param $id
     * @return int
     */
    public static function addWeChatUserAdmin($id)
    {
        if (!self::checkAdminStatus($id)) {
            return -1;
        }

        $code = Request::get('code', '');

        $webApp = new WXWebAppData();
        $user_id = 0;

        $access_token = $webApp->getWebAppAccessToken($code);
        if (empty($access_token) || !isset($access_token['access_token']) || empty($access_token['access_token'])) {
            throw new \Exception('[微信网站应用]获取access_token失败，access_token为空');
        }

        // 判断是否有unionid，并且在微信用户数据库中有数据存在
        if (isset($access_token['unionid']) && !empty($access_token['unionid'])) {
            $we_chat_user = WeChatUser::with(['admin' => function($query) {
                $query->field(['id']);
            }])
                ->where([['unionid','=',$access_token['unionid']]])
                ->find();
            if (!$we_chat_user) {
                return -2;
            }

            // 需要授权的用户已在用户列表中
            // 判断用户的web_openid是否在存在
            if (!empty($we_chat_user->web_openid) && ($we_chat_user->web_openid == $access_token['openid'])) {
                // 用户存在（更新用户相关信息）
                $user_id = $we_chat_user->id;
                self::updateNewWeChatUser($access_token['access_token'], $access_token['openid'], true, $user_id);
            } else {
                // 添加web_openid
                $user_id = self::updateNewWeChatUser($access_token['access_token'], $access_token['openid']);
            }
        } else {
            $user_id = self::updateNewWeChatUser($access_token['access_token'], $access_token['openid']);
        }

        // 判断用户是否已经绑定过管理员
//        $we_chat_admin = static::with(['weChatUser' => function($query) use ($user_id) {
//            $query->where([['id','=',$user_id]]);
//        }])->where([['id','<>',$id]])
//            ->find();
        $we_chat_admin = (!$we_chat_user || !$we_chat_user->admin || $we_chat_user->admin->isEmpty()) ? [] : $we_chat_user->admin->toArray()[0];

//        return $we_chat_admin;

        if ($we_chat_admin && $we_chat_admin['id'] != $id) {
            // 已经绑定过管理员
            // 先删除旧的绑定信息
            $admin = static::find($we_chat_admin['id']);
            $admin->weChatUser()->detach($user_id);
//            return $we_chat_admin;
        }

        // 没有绑定过管理员
        $admin = static::find($id);
        $admin->weChatUser()->attach($user_id);

//        return $admin;

        return 0;
    }

    /**
     * 获取授权微信管理员列表分页数据
     * @param $params
     * @return \think\Paginator
     */
    public static function getWeChatAdminPaginateList($params)
    {
        $validate = new IDMustBeRequire();
        if (!$validate->check(['id'=>$params['id']])) {
            throw new ParameterException([
                'msg' => $validate->getError(),
            ]);
        }

        static::validatePaginationData($params);

        $we_chat_admin = static::with(['weChatUser' => function($query) use($params) {
            $query->field(['id']);
//            $query = $query->field(['id','nick_name','avatar_url','web_openid']);

//            foreach ($params as $name => $value) {
//                $value = trim($value);
//                switch ($name) {
//                    case 'nick_name' :
//                        if (!empty($value)) {
//                            $likeText = "from_base64(nick_name) like '%{$value}%'";
//                            $query = $query->whereRaw($likeText);
//                        }
//                        break;
//                }
//            }

//            $query->paginate([
//                'page' => $params['page'],
//                'list_rows' => $params['limit']
//            ], false);
        }])->find($params['id']);

        $we_chat_user = $we_chat_admin->weChatUser->toArray();
        $we_chat_user_ids = array_column($we_chat_user,'id');
        $we_chat_user_ids_string = empty($we_chat_user_ids) ? '0' : implode(',', $we_chat_user_ids);
        $user_ids_exp = new Raw('field(id,'.$we_chat_user_ids_string.')');

        $weChatUser = WeChatUser::where([['id','in',$we_chat_user_ids]])
            ->order($user_ids_exp);
        foreach ($params as $name => $value) {
            $value = trim($value);
            switch ($name) {
                case 'nick_name' :
                    if (!empty($value)) {
                        $likeText = "from_base64(nick_name) like '%{$value}%'";
                        $weChatUser = $weChatUser->whereRaw($likeText);
                    }
                    break;
            }
        }

        return $weChatUser->paginate([
            'page' => $params['page'],
            'list_rows' => $params['limit']
        ], false);
    }

    /**
     * 删除微信管理员
     * @param $data
     * @return bool
     */
    public static function deleteWeChatAdmin($data)
    {
        $validate = new Validate();
        if (!$validate->scene('delete_we_chat_admin')->check($data)) {
            throw new ParameterException([
                'msg' => $validate->getError()
            ]);
        }

        // 查询用户是否存在
        $we_chat_user = static::with(['weChatUser' => function($query) use ($data) {
            $query->where([['id','=',$data['user_id']]]);
        }])->where([['id','=',$data['id']]])
            ->find();

        if (!$we_chat_user || !$we_chat_user->weChatUser) {
            throw new UserException();
        }

        $delete_num = $we_chat_user->weChatUser()->detach($data['user_id']);

        return $delete_num ? true : false;
    }

    /**
     * 添加/更新来自网站应用的用户数据
     * @param $access_token
     * @param $openid
     * @param $is_update
     * @param $user_id
     */
    private static function updateNewWeChatUser($access_token, $openid, $is_update = false, $user_id = 0)
    {
        // 获取用户详细信息
        $user_data = (new WXWebAppData())->getUserInfo($access_token, $openid);

        if (!isset($user_data['openid']) || empty($user_data['openid'])) {
            throw new \Exception('[微信网站应用]获取用户信息失败，openid为空');
        }

        // 更新用户数据
        if ($is_update) {
            $user_data['id'] = $user_id;
            return WeChatUser::updateUserInfoByWebApp($user_data);
        }

        // 添加新用户
        return WeChatUser::addUserByWebApp($user_data);
    }

    /**
     * 判断当前管理员是否为开启状态
     * @param $id
     * @return bool
     */
    private static function checkAdminStatus($id)
    {
        $admin = static::where([['id','=',$id],['status','=',1]])
            ->find();

        return $admin ? true : false;
    }

    /**
     * 得到对应的保存token的key
     * @param $code
     * @return string
     */
    private static function getTokenRedisKey($code)
    {
        return self::CODE_TOKEN_KEY_PREFIX . $code;
    }
}